package com.example.wx.dailyreport.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.wx.dailyreport.mapper.AuthorityMapper;
import com.example.wx.dailyreport.mapper.RoleAuthorityMapper;
import com.example.wx.dailyreport.mapper.UserAuthorityMapper;
import com.example.wx.dailyreport.pojo.Authority;
import com.example.wx.dailyreport.pojo.RoleAuthority;
import com.example.wx.dailyreport.pojo.UserAuthority;
import com.example.wx.dailyreport.service.AuthorityService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.LinkedList;
import java.util.Set;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author hulinbo
 * @since 2020-07-30
 */
@Service
@Transactional
public class AuthorityServiceImpl extends ServiceImpl<AuthorityMapper, Authority> implements AuthorityService {

    private static final int SIZE = 100;

    @Autowired
    private AuthorityMapper authorityMapper;

    @Autowired
    private RoleAuthorityMapper roleAuthorityMapper;

    @Autowired
    private UserAuthorityMapper userAuthorityMapper;

    @Override
    public Set<String> selectAuthorityByRoleIds(int[] ids) {
        return authorityMapper.selectAuthorityByRoleIds(ids);
    }

    @Override
    public IPage<Authority> selectAuthorityInPage(Authority authority, int page, int limit) {
        IPage<Authority> iPage = new Page<>(page, limit);
        QueryWrapper<Authority> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().like(StringUtils.isNotEmpty(authority.getAuthority()), Authority::getAuthority, authority.getAuthority())
                .like(StringUtils.isNotEmpty(authority.getIntroduction()), Authority::getIntroduction, authority.getIntroduction());
        return authorityMapper.selectPage(iPage, queryWrapper);
    }

    @Override
    public boolean insertAuthority(Authority authority) {
        authority.setFlag((long) Math.pow(2, authorityMapper.selectCount(new QueryWrapper<>())));
        return authorityMapper.insert(authority) > 0;
    }

    @Override
    public boolean deleteAuthorityById(Integer id) {
        long flag = authorityMapper.selectById(id).getFlag();
        int delete = authorityMapper.deleteById(id);

        UpdateWrapper<RoleAuthority> roleAuthorityUpdateWrapper = new UpdateWrapper<>();
        roleAuthorityUpdateWrapper.lambda().eq(RoleAuthority::getAuthorityId, id);
        roleAuthorityMapper.delete(roleAuthorityUpdateWrapper);

        UpdateWrapper<UserAuthority> userAuthorityUpdateWrapper = new UpdateWrapper<>();
        userAuthorityUpdateWrapper.lambda().eq(UserAuthority::getAuthorityId, id);
        userAuthorityMapper.delete(userAuthorityUpdateWrapper);

        QueryWrapper<Authority> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().gt(Authority::getFlag, flag);

        Integer count = authorityMapper.selectCount(queryWrapper);
        int page = (int) Math.ceil(count / (double) SIZE);
        if (page > 0) {
            for (int i = 0; i < page; i++) {
                IPage<Authority> iPage = new Page<>(i * SIZE, SIZE);
                IPage<Authority> roleIPage = authorityMapper.selectPage(iPage, queryWrapper);
                LinkedList<Authority> pageRecords = new LinkedList<>(roleIPage.getRecords());
                int len = pageRecords.size();
                for (int j = 0; j < len; j++) {
                    Authority authority = pageRecords.removeFirst();
                    authority.setFlag(flag * (long) Math.pow(2, j));
                    pageRecords.addLast(authority);
                }
                updateBatchById(pageRecords);
            }
        }
        return delete > 0;
    }

}
